winsafe\kernel\handles/
hprocess.rs

1#![allow(non_camel_case_types, non_snake_case)]
2
3use crate::co;
4use crate::decl::*;
5use crate::guard::*;
6use crate::kernel::{ffi, privs::*};
7
8handle! { HPROCESS;
9	/// Handle to a
10	/// [process](https://learn.microsoft.com/en-us/windows/win32/procthread/processes-and-threads).
11	/// Originally just a `HANDLE`.
12}
13
14impl HPROCESS {
15	/// [`CheckRemoteDebuggerPresent`](https://learn.microsoft.com/en-us/windows/win32/api/debugapi/nf-debugapi-checkremotedebuggerpresent)
16	/// function.
17	#[must_use]
18	pub fn CheckRemoteDebuggerPresent(&self) -> SysResult<bool> {
19		let mut present = 0;
20		bool_to_sysresult(unsafe { ffi::CheckRemoteDebuggerPresent(self.ptr(), &mut present) })
21			.map(|_| present != 0)
22	}
23
24	/// [`FlushInstructionCache`](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-flushinstructioncache)
25	/// function.
26	pub fn FlushInstructionCache(
27		&self,
28		base_address: *mut std::ffi::c_void,
29		size: usize,
30	) -> SysResult<()> {
31		bool_to_sysresult(unsafe { ffi::FlushInstructionCache(self.ptr(), base_address, size) })
32	}
33
34	/// [`GetCurrentProcess`](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentprocess)
35	/// function.
36	#[must_use]
37	pub fn GetCurrentProcess() -> HPROCESS {
38		HPROCESS(unsafe { ffi::GetCurrentProcess() })
39	}
40
41	/// [`GetExitCodeProcess`](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getexitcodeprocess)
42	/// function.
43	#[must_use]
44	pub fn GetExitCodeProcess(&self) -> SysResult<u32> {
45		let mut exit_code = 0u32;
46		bool_to_sysresult(unsafe { ffi::GetExitCodeProcess(self.ptr(), &mut exit_code) })
47			.map(|_| exit_code)
48	}
49
50	/// [`GetGuiResources`](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getguiresources)
51	/// function.
52	#[must_use]
53	pub fn GetGuiResources(&self, flags: co::GR) -> SysResult<u32> {
54		match unsafe { ffi::GetGuiResources(self.ptr(), flags.raw()) } {
55			0 => Err(GetLastError()),
56			count => Ok(count),
57		}
58	}
59
60	/// [`GetPriorityClass`](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getpriorityclass)
61	/// function.
62	#[must_use]
63	pub fn GetPriorityClass(&self) -> SysResult<co::PRIORITY_CLASS> {
64		match unsafe { ffi::GetPriorityClass(self.ptr()) } {
65			0 => Err(GetLastError()),
66			pc => Ok(unsafe { co::PRIORITY_CLASS::from_raw(pc) }),
67		}
68	}
69
70	/// [`GetProcessHandleCount`](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getprocesshandlecount)
71	/// function.
72	#[must_use]
73	pub fn GetProcessHandleCount(&self) -> SysResult<u32> {
74		let mut count = 0u32;
75		bool_to_sysresult(unsafe { ffi::GetProcessHandleCount(self.ptr(), &mut count) })
76			.map(|_| count)
77	}
78
79	/// [`GetProcessId`](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getprocessid)
80	/// function.
81	#[must_use]
82	pub fn GetProcessId(&self) -> SysResult<u32> {
83		match unsafe { ffi::GetProcessId(self.ptr()) } {
84			0 => Err(GetLastError()),
85			id => Ok(id),
86		}
87	}
88
89	/// [`GetProcessTimes`](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getprocesstimes)
90	/// function.
91	///
92	/// Returns, respectively:
93	///
94	/// 1. creation time;
95	/// 2. exit time;
96	/// 3. kernel time;
97	/// 4. user time.
98	///
99	/// # Examples
100	///
101	/// ```no_run
102	/// use winsafe::{self as w, prelude::*, co};
103	///
104	/// let hprocess: w::HPROCESS; // initialized somewhere
105	/// # let hprocess = w::HPROCESS::NULL;
106	///
107	/// let (creation, exit, kernel, user) = hprocess.GetProcessTimes()?;
108	/// # w::SysResult::Ok(())
109	/// ```
110	pub fn GetProcessTimes(&self) -> SysResult<(FILETIME, FILETIME, FILETIME, FILETIME)> {
111		let (mut creation, mut exit, mut kernel, mut user) =
112			(FILETIME::default(), FILETIME::default(), FILETIME::default(), FILETIME::default());
113
114		bool_to_sysresult(unsafe {
115			ffi::GetProcessTimes(
116				self.ptr(),
117				pvoid(&mut creation),
118				pvoid(&mut exit),
119				pvoid(&mut kernel),
120				pvoid(&mut user),
121			)
122		})
123		.map(|_| (creation, exit, kernel, user))
124	}
125
126	/// [`IsProcessCritical`](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-isprocesscritical)
127	/// function.
128	#[must_use]
129	pub fn IsProcessCritical(&self) -> SysResult<bool> {
130		let mut critical = 0;
131		bool_to_sysresult(unsafe { ffi::IsProcessCritical(self.ptr(), &mut critical) })
132			.map(|_| critical != 0)
133	}
134
135	/// [`IsWow64Process`](https://learn.microsoft.com/en-us/windows/win32/api/wow64apiset/nf-wow64apiset-iswow64process)
136	/// function.
137	#[must_use]
138	pub fn IsWow64Process(&self) -> SysResult<bool> {
139		let mut wow64 = 0;
140		match unsafe { ffi::IsWow64Process(self.ptr(), &mut wow64) } {
141			0 => Err(GetLastError()),
142			_ => Ok(wow64 != 0),
143		}
144	}
145
146	/// [`OpenProcess`](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-openprocess)
147	/// function.
148	///
149	/// This method will return
150	/// [`ERROR::INVALID_PARAMETER`](crate::co::ERROR::INVALID_PARAMETER) if you
151	/// try to open a system process.
152	#[must_use]
153	pub fn OpenProcess(
154		desired_access: co::PROCESS,
155		inherit_handle: bool,
156		process_id: u32,
157	) -> SysResult<CloseHandleGuard<HPROCESS>> {
158		unsafe {
159			ptr_to_sysresult_handle(ffi::OpenProcess(
160				desired_access.raw(),
161				inherit_handle as _,
162				process_id,
163			))
164			.map(|h| CloseHandleGuard::new(h))
165		}
166	}
167
168	/// [`QueryFullProcessImageName`](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-queryfullprocessimagenamew)
169	/// function.
170	#[must_use]
171	pub fn QueryFullProcessImageName(&self, flags: co::PROCESS_NAME) -> SysResult<String> {
172		let mut buf = WString::new_alloc_buf(MAX_PATH + 1);
173		let mut sz = buf.buf_len() as u32;
174
175		bool_to_sysresult(unsafe {
176			ffi::QueryFullProcessImageNameW(self.ptr(), flags.raw(), buf.as_mut_ptr(), &mut sz)
177		})
178		.map(|_| buf.to_string())
179	}
180
181	/// [`QueryProcessAffinityUpdateMode`](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-queryprocessaffinityupdatemode)
182	/// function.
183	#[must_use]
184	pub fn QueryProcessAffinityUpdateMode(&self) -> SysResult<co::PROCESS_AFFINITY> {
185		let mut affinity = co::PROCESS_AFFINITY::default();
186		bool_to_sysresult(unsafe {
187			ffi::QueryProcessAffinityUpdateMode(self.ptr(), affinity.as_mut())
188		})
189		.map(|_| affinity)
190	}
191
192	/// [`QueryProcessCycleTime`](https://learn.microsoft.com/en-us/windows/win32/api/realtimeapiset/nf-realtimeapiset-queryprocesscycletime)
193	/// function.
194	#[must_use]
195	pub fn QueryProcessCycleTime(&self) -> SysResult<u64> {
196		let mut t = 0u64;
197		bool_to_sysresult(unsafe { ffi::QueryProcessCycleTime(self.ptr(), &mut t) }).map(|_| t)
198	}
199
200	/// [`ReadProcessMemory`](https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-readprocessmemory)
201	/// function.
202	///
203	/// Reads at most `buffer.len()` bytes. Returns how many bytes were actually
204	/// read.
205	#[must_use]
206	pub fn ReadProcessMemory(
207		&self,
208		base_address: *mut std::ffi::c_void,
209		buffer: &mut [u8],
210	) -> SysResult<usize> {
211		let mut bytes_read = 0usize;
212		bool_to_sysresult(unsafe {
213			ffi::ReadProcessMemory(
214				self.ptr(),
215				base_address,
216				buffer.as_ptr() as _,
217				buffer.len(),
218				&mut bytes_read,
219			)
220		})
221		.map(|_| bytes_read)
222	}
223
224	/// [`SetPriorityClass`](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setpriorityclass)
225	/// function.
226	pub fn SetPriorityClass(&self, prority_class: co::PRIORITY_CLASS) -> SysResult<()> {
227		bool_to_sysresult(unsafe { ffi::SetPriorityClass(self.ptr(), prority_class.raw()) })
228	}
229
230	/// [`SetProcessAffinityUpdateMode`](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setprocessaffinityupdatemode)
231	/// function.
232	pub fn SetProcessAffinityUpdateMode(&self, flags: co::PROCESS_AFFINITY) -> SysResult<()> {
233		bool_to_sysresult(unsafe { ffi::SetProcessAffinityUpdateMode(self.ptr(), flags.raw()) })
234	}
235
236	/// [`SetProcessPriorityBoost`](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setprocesspriorityboost)
237	/// function.
238	pub fn SetProcessPriorityBoost(&self, disable_priority_boost: bool) -> SysResult<()> {
239		bool_to_sysresult(unsafe {
240			ffi::SetProcessPriorityBoost(self.ptr(), disable_priority_boost as _)
241		})
242	}
243
244	/// [`TerminateProcess`](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-terminateprocess)
245	/// function.
246	pub fn TerminateProcess(&self, exit_code: u32) -> SysResult<()> {
247		bool_to_sysresult(unsafe { ffi::TerminateProcess(self.ptr(), exit_code) })
248	}
249
250	/// [`VirtualQueryEx`](https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualqueryex)
251	/// function.
252	#[must_use]
253	pub fn VirtualQueryEx(
254		&self,
255		address: Option<*mut std::ffi::c_void>,
256	) -> SysResult<MEMORY_BASIC_INFORMATION> {
257		let mut mbi = MEMORY_BASIC_INFORMATION::default();
258		match unsafe {
259			ffi::VirtualQueryEx(
260				self.ptr(),
261				address.unwrap_or(std::ptr::null_mut()),
262				pvoid(&mut mbi),
263				std::mem::size_of::<MEMORY_BASIC_INFORMATION>(),
264			)
265		} {
266			0 => Err(GetLastError()),
267			_ => Ok(mbi),
268		}
269	}
270
271	/// [`WaitForSingleObject`](https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitforsingleobject)
272	/// function.
273	pub fn WaitForSingleObject(&self, milliseconds: Option<u32>) -> SysResult<co::WAIT> {
274		unsafe { HEVENT::from_ptr(self.ptr()) }.WaitForSingleObject(milliseconds)
275	}
276
277	/// [`WriteProcessMemory`](https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-writeprocessmemory)
278	/// function.
279	///
280	/// Returns how many bytes were actually written.
281	pub fn WriteProcessMemory(
282		&self,
283		base_address: *mut std::ffi::c_void,
284		buffer: &[u8],
285	) -> SysResult<usize> {
286		let mut bytes_written = 0usize;
287		bool_to_sysresult(unsafe {
288			ffi::WriteProcessMemory(
289				self.ptr(),
290				base_address,
291				buffer.as_ptr() as _,
292				buffer.len(),
293				&mut bytes_written,
294			)
295		})
296		.map(|_| bytes_written)
297	}
298}